#pragma once

#include "Game/Process/RenderProcess.h"
#include "Render/Texture/Picture2DTexture.h"
#include "Render/Texture/RenderTarget.h"
#include "Render/Tradition/RHIRenderPass.h"
#include "Render/Tradition/GraphicsPipeline.h"
#include "Render/Texture/ColorRenderTarget.h"
#include "Render/Texture/CubemapTexture.h"
#include "Render/Texture/DepthRenderTarget.h"
#include "Render/Shader/RHIDescriptor.h"
#include "Render/Tradition/RHIFramebuffer.h"
#include "LocalEntity.h"
#include "LocalShader.h"
#include "Render/Raytracing/RayTracingPipeline.h"
#include "Render/Raytracing/TopLevelAccelerationStructure.h"
#include "Render/Tradition/ComputePipeline.h"


class RayTracingComputeProcess : public RenderProcess
{
	DECLARE_PROCESS(RayTracingComputeProcess)

	struct Ubo
	{
		glm::mat4 projview;
		glm::mat4 viewInverse;
		glm::mat4 projInverse;
		int32 frame;
	};

protected:

	virtual void OnInit() override;

	virtual void OnTick(float deltaTime) override;

	virtual void OnResize() override;

	uint32 BuildBVHTree(uint32 l, uint32 r, uint32 n);

protected:

	int32 mMaxFrame;

	glm::mat4 mLastView;

	glm::mat4 mLastProj;

	int32 mFrame;

	std::function<bool(const TriangleGpu&, const TriangleGpu&)> fCompareX;

	std::function<bool(const TriangleGpu&, const TriangleGpu&)> fCompareY;

	std::function<bool(const TriangleGpu&, const TriangleGpu&)> fCompareZ;

	std::vector<LocalEntity*> mLocalEntitys;

	std::vector<MaterialGpu> mAllMaterial;

	std::vector<VertexGpu> mAllVertex;

	std::vector<TriangleGpu> mAllTriangle;

	std::vector<BVHNodeGpu> mAllBVHNode;



	RefCountPtr<RHIBuffer> mUboBuffer;

	RefCountPtr<RHIBuffer> mMaterialBuffer;

	RefCountPtr<RHIBuffer> mVertexBuffer;

	RefCountPtr<RHIBuffer> mTriangleBuffer;

	RefCountPtr<RHIBuffer> mBVHNodeBuffer;

	RefCountPtr<RHITexture> mCubemapTexture;

	RefCountPtr<RHISampler> mCubemapSampler;

	RefCountPtr<RHITexture> mResultTexture;

	RefCountPtr<RHITexture> mColorTexture;



	RefCountPtr<RHIDescriptor> mDescriptor;

	DescriptorMask mDescriptorMask;

	RefCountPtr<ComputePipeline> mPipeline;

	RefCountPtr<RHICommandBuffer> mCommandBuffer;

	RefCountPtr<RHISemaphore> mWaitGraphicsSemaphore;

	RefCountPtr<RHISemaphore> mSignalComputeSemaphore;

};
